import { message } from 'antd';
import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import process from 'process';
import NProgress from '../components/nprogress';
import { store } from '../store';
import { AxiosCanceler } from './AxiosCancel';
import { checkStatus } from './CheckStatus';
import { ResultCode } from './config/Request';

const config = {
    // 默认地址请求地址，可在 .env 开头文件中修改
    baseURL: process.env.API_URL as string,
    // 设置超时时间（10s）
    timeout: 10000,
    // 跨域时候允许携带凭证
    withCredentials: true,
};

const request = axios.create(config);

const axiosCancel = new AxiosCanceler();

// 请求拦截器
request.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        NProgress.start();
        axiosCancel.addPending(config);
        const token = store.getState().user.token;
        if (token) {
            return {
                ...config,
                headers: { ...config.headers, 'x-access-token': token },
            } as unknown as InternalAxiosRequestConfig;
        }
        return config;
    },
    (error: AxiosError) => {
        return Promise.reject(error);
    }
);

// 响应拦截器
request.interceptors.response.use(
    (response: AxiosResponse) => {
        const { data, config } = response;
        NProgress.done();
        axiosCancel.removePending(config);

        // token过期
        if (data.code === ResultCode.OVERDUE) {
            return Promise.reject(data);
        }

        // 响应状态码错误
        if (data.code !== ResultCode.SUCCESS) {
            message.error(data.msg);
            return Promise.reject(data);
        }

        return Promise.resolve(data);
    },
    async (error: AxiosError) => {
        const { response } = error;
        NProgress.done();
        // 请求超时单独判断，请求超时没有 response
        if (error.message.indexOf('timeout') !== -1) message.error('请求超时，请稍后再试');

        // 根据响应的错误状态码，做不同的处理
        if (response) checkStatus(response.status);

        // 服务器结果都没有返回(可能服务器错误可能客户端断网) 断网处理:可以跳转到断网页面
        if (!window.navigator.onLine) window.location.hash = '/500';

        return Promise.reject(error);
    }
);

export default request;
